package fr.lip6.move.care

import java.util.ArrayList
import java.util.List
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.IFileSystemAccess
import sdmakerz_v1.coresyntax.generator.interfaces.IConfigData
import sdmakerz_v1.coresyntax.generator.interfaces.IContext
import sdmakerz_v1.coresyntax.generator.interfaces.IDiagramRefData
import sdmakerz_v1.coresyntax.generator.interfaces.IInputData
import sdmakerz_v1.coresyntax.sDMakerV1.Actor
import sdmakerz_v1.coresyntax.sDMakerV1.Alt
import sdmakerz_v1.coresyntax.sDMakerV1.Call
import sdmakerz_v1.coresyntax.sDMakerV1.Diagram
import sdmakerz_v1.coresyntax.sDMakerV1.DiagramElement
import sdmakerz_v1.coresyntax.sDMakerV1.DiagramRef
import sdmakerz_v1.coresyntax.sDMakerV1.Obj
import sdmakerz_v1.coresyntax.sDMakerV1.Loop
import sdmakerz_v1.coresyntax.sDMakerV1.Opt
import sdmakerz_v1.coresyntax.generator.interfaces.ISDMakerGenerator
import sdmakerz_v1.coresyntax.SDMakerV1RuntimeModule
import sdmakerz_v1.coresyntax.generator.SDMakerV1IDProvider
import sdmakerz_v1.coresyntax.generator.interfaces.ISDMakerFolderLevelGen
import sdmakerz_v1.coresyntax.generator.interfaces.ISDMakerModelLevelGen
import org.eclipse.emf.ecore.EObject
import sdmakerz_v1.coresyntax.sDMakerV1.SDMakerModel

/** 
 * La classe principale de generation vers CARE
 *
 * @author pstl-team
 */
class CareGen implements ISDMakerModelLevelGen {
 
    /** Un element doit etre ajoute dans la sequence principale
        si il n'est inclut dans aucun autre et qu'il represente un
        un element existant dans CARE. Il sera alors ajouter a la BlockList
        principale du Main (voir utilisation de la classe Main dans le package
        programs de CARE). Par exemple, une declaration de methode n'as pas 
        d'equivalent en CARE. */
    private List<CompileResult> mainSequence;
    
    private CareActorGen actorGen;
    private CareAltGen altGen;
    private CareCallGen callGen;
    private CareDiagramGen diagramGen;
    private CareDiagramRefGen diagramRefGen;
    private CareLoopGen loopGen;
    private CareObjGen objGen;
    private CareOptGen optGen;



	new(){
		actorGen= new CareActorGen(this);
		altGen= new CareAltGen(this);
		callGen= new CareCallGen(this);
		diagramGen= new CareDiagramGen(this);
		diagramRefGen= new CareDiagramRefGen(this);
		loopGen= new CareLoopGen(this);
		objGen= new CareObjGen(this);
		optGen= new CareOptGen(this);
	}
	
	override boolean canHandle(Resource input) {
		var boolean canHandle= false;

		for(EObject eo : input.
							allContents.
							toIterable){
			if(eo instanceof SDMakerModel){
				canHandle= true;
			}
		}	

		return canHandle
	}
	
	def public addToMainSequence(CompileResult compRes){
		mainSequence.add(compRes);
	}
	
	def public List<CompileResult> getMainSequence(){
		return mainSequence;
	}

	override doGenerate(IContext context, IFileSystemAccess fsa) {
		var IInputData inputData= context.getInputData;
		var Resource input= inputData.getInput;
		
		for(diagram: input.allContents.toIterable.filter(typeof(Diagram))) {	
			var IConfigData configData= 
				SDMakerV1RuntimeModule::
					bindIConfigData.newInstance;
			var IDiagramRefData refData= 
				SDMakerV1RuntimeModule::
					bindIDiagramRefData.newInstance;
			
			configData.init(null);
			refData.init(diagram, null, null, diagram.name);
			
			context.setContextDiagram(diagram);
			context.setConfigData(configData);
			context.setDiagramRefData(refData);
		
			mainSequence= new ArrayList<CompileResult>();
			SDMakerV1IDProvider::reinitIDs
			fsa.generateFile("care-gen/"+
				             inputData.getOutputBasedName+"_"+
				             diagram.name + ".java", 
				             diagramGen.compile(context, diagram)
				             			.charSequenceResult
				            )
		}	
	}	
		
	def public 
    CompileResult compile(IContext context, DiagramElement elt){
    	
    	switch elt {
            Actor : {
                actorGen.compile(context, elt as Actor);                    
            }
            Obj : {
            	objGen.compile(context, elt as Obj);
            }
            Call : {
                callGen.compile(context, elt as Call);
            }
            Alt : {
                altGen.compile(context, elt as Alt);
            }
            Loop : {
                loopGen.compile(context, elt as Loop);
            }
            Opt : {
                optGen.compile(context, elt as Opt);
            }
            DiagramRef : {
                diagramRefGen.compile(context, elt as DiagramRef);
            }
            default: {
            	return new CompileResult(
            					'''
            					CareGen.compile(IContext context, DiagramElement elt): 
            					not supported DiagramElement: «elt.getClass().getName»''',
            					null,
            					true)
            }
        }
		
//		for(eval: input.allContents.toIterable.filter(typeof(Eval))){
//	
//			for(ConfigRef configRef: eval.configs){
//				var String filename= null; 
//				var Resource diagramInput= input;
//				var IDiagramRefData diagramRefData= new DiagramRefDataImpl();
//				var Diagram diag= null;
//				
//				var Resource configInput= input;
//				var IConfigData configData= new ConfigDataImpl();
//				var Config conf= null;				
//		
//				context.setInput(inputData);
//				filename= SDMakerToCareUtils::computeEvalFinalName(
//					                       context, eval, configRef);
//				
//				diagramInput= context.getDiagramInput(eval.diagRef.name);
//				diag= context.findDiagram(eval.diagRef.name);
//				conf= context.findConfig(configRef.name);
//				
//				configData.init(conf);
//				diagramRefData.init(diag, null, null, filename);
//				
//				if(diagramInput!=context.getInputData.getInput){
//					context.setInput(new InputDataImpl (diagramInput));
//				}
//				
//				context.init(diag, configData, diagramRefData, 
//					         new SDMakerToCareUtils());
//					
//				mainSequence= new ArrayList<CompileResult>();
//				SDMakerToCareUtils::reinitIDs();
//				fsa.generateFile(filename+".java", compileDiagram(diag, context))
//			}
//		}
	}

//	def CharSequence compileDiagram(Diagram d, IContext context) { 
//        var List<IInterfaceData> usedClass= new ArrayList<IInterfaceData>();
//        var List<CompileResult> compileResults= new ArrayList<CompileResult>();
//        
//        for(elt : d.diagram_elts){
//        	
//        	if(elt instanceof Obj){
//        		var Obj obj = elt as Obj;
//        		var IInterfaceData iid= 
//        			context.getInterfaceDataByName(
//        				context.inputData, obj.type.identifier);
//        		if(SDMakerUtils::contains(usedClass, iid)==false){
//        			usedClass.add(iid);
//        		}
//        	}
//        	
//        	var CompileResult compRes = compileEltCare(elt, context)
//        	
//        	if(compRes.isAddableToEntryPoint){
//        		mainSequence.add(compRes);
//        	}
//        	compileResults.add(compRes);
//        }
//        
//        var CharSequence charSequenceResult= 
//        '''
//        package programs;
//        
//        import java.util.ArrayList;
//        import program.*;
//        import traces.*;
//        
//        «context.getConfigData.printImports»
//        
//        
//«««        public class «context.ou»«context.getDiagramRefData.diagNewName» {     
//        public class «SDMakerUtils::computeSimpleName(context.inputData.outputBasedName.replaceAll("/","\\."))»_«d.name» {     
//            public static Main create(){
//                int i= 0;
//                ArrayList<Actor> actors= new ArrayList<Actor>();
//                
//                ObjectClass actorClass=new ObjectClass("Actor");
//                «FOR IInterfaceData interfaceDatas: usedClass»
//                ObjectClass «interfaceDatas.interfaceID»= new ObjectClass("«interfaceDatas.getQualifiedName»");
//                «ENDFOR»
//                
//                «FOR compRes: compileResults»
//                    «compRes.charSequenceResult»
//                «ENDFOR»
//                
//                «var String mainID= "entry_point_id"+SDMakerToCareUtils::nextID»
//                ArrayList<Block> «mainID» = new ArrayList<Block>();
//                «FOR elt: mainSequence»
//                «mainID».add(«elt.eltID»);
//                «ENDFOR»
//                return new Main(«mainID», actors, 200);
//            } 
//        
//            public static void main(String[] args) {
//                Main sd=create();
//                boolean ok=sd.saveModel("«context.getDiagramRefData.diagNewName»");
//                if (ok){
//                    sd.genereAllTraces("«context.getDiagramRefData.diagNewName»", 100);
//                }
//                
//                
//    	        «context.getConfigData.printEval»
//            }
//        }
//        '''
//
//        return charSequenceResult;
//    }
   

//    /* ***************************
//     * Compilation des acteurs  **
//     * ***************************/
//    def CompileResult compileActorCare(Lifeline actor, IContext context) {
//    
//    var CharSequence charSequenceResult=
//    '''    
//                                      
//    Actor «actor.name» = new Actor("«actor.name»", actorClass);   
//    actors.add(«actor.name»);                                                 
//    '''
//    
//    return new CompileResult()
//                .setCharSequenceResult(charSequenceResult)
//                .setEltID(actor.name)
//                .setIsAddableToMainSequence(false)
//    }
//    
//    /* ***************************
//     * Compilation des objets ****
//     * ***************************/
//    def CompileResult compileObjectCare(Obj obj, IContext context) {
//        var CompileResult compileResult= CompileResult::emptyResult;
//        var newObjName= context.getDiagramRefData().getNewName(obj.name);
//        var IInterfaceData interfaceData= null;
//        var CharSequence charSequenceResult= null;
//
//        if(newObjName.compareTo(obj.name)==0){
//            
//            /* On compile un Obj qui n'est pas une reference.
//             * -On conserve une information qui permet de retrouver l'interface
//             *  associé au nom.
//             * -On doit creer l'acteur dans le main */
//           interfaceData= context.getInterfaceDataByName(context.inputData, obj.type.identifier);
//           //interfaceData.addName(obj.name); 
//           
//           charSequenceResult=
//           '''
//           Actor «obj.name» = new Actor("«obj.name»", «interfaceData.interfaceID»); 
//           actors.add(«obj.name»);
//           '''
//           
//           compileResult= new CompileResult()
//                              .setCharSequenceResult(charSequenceResult)
//                              .setEltID(obj.name)
//                              .setIsAddableToMainSequence(false)
//        }
//        
//        
//        return compileResult;
//    }
//
//    /* *************************************
//     * Compilation des appels de methode ***
//     * *************************************/
//    def CompileResult compileCallCare(Call call, IContext context) {
//    	var java.util.ArrayList<CompileResult> nestedResults= new java.util.ArrayList<CompileResult>()
//        var CompileResult compRes
//        var callID= call.name+"_id"+SDMakerToCareUtils::nextID
//        var callerName= context.getDiagramRefData.getNewName(call.caller);
//        var calledName= context.getDiagramRefData.getNewName(call.called);
//        
//        var CharSequence charSequenceResult=
//        '''
//    
//        «FOR elt: call.nested_calls»
//«««        «IF !(elt instanceof Declaration)»
//        «SDMakerToCareUtils::toNullExp(compRes= compileEltCare(elt, context))»
//        «SDMakerToCareUtils::toNullExp(nestedResults.add(compRes))» 
//«««        «ENDIF»
//        «ENDFOR»
//    
//        «IF nestedResults.size() == 0»
//        Call «callID» = new Call(new Statement("S" + i++,«callerName»,new Method("«call.name»",new ArrayList<ObjectInstance>(),«context.getInterfaceDataByObjectName(calledName).interfaceID»),«calledName»));        
//        «ELSEIF nestedResults.size() == 1»
//        /* NESTED CALL: «callID» */
//        «nestedResults.get(0).charSequenceResult»
//        /* FINALIZING «callID»*/
//        Call «callID» = new Call(new Statement("S" + i++,«callerName»,new Method("«call.name»",new ArrayList<ObjectInstance>(),«context.getInterfaceDataByObjectName(calledName).interfaceID»),«calledName»), «nestedResults.get(0).eltID»);
//        «ELSE»
//        /* NESTED CALL: «callID» */
//        BlockList bloc_«callID»= new BlockList();
//        «FOR nestedResult: nestedResults»
//        «nestedResult.charSequenceResult»
//        «ENDFOR»
//    
//        /* add(s) for «callID» */
//        «FOR nestedResult: nestedResults»
//        bloc_«callID».add(«nestedResult.eltID»);
//        «ENDFOR»
//    
//        /* FINALIZING «callID»*/
//        Call «callID» = new Call(new Statement("S" + i++,«calledName»,new Method("«call.name»",new ArrayList<ObjectInstance>(),«context.getInterfaceDataByObjectName(calledName).interfaceID»),«calledName»), bloc_«callID»);
//        «ENDIF»
//        '''
//    
//    
//        return new CompileResult()
//                    .setCharSequenceResult(charSequenceResult)
//                    .setEltID(callID)
//                    .setIsAddableToMainSequence(true)
//    }
//
//    /* *************************************
//     * Compilation des alternatives  *******
//     * *************************************/
//    def CompileResult compileAltCare(Alt alt, IContext context) { 
//    var IConfigData config= context.getConfigData
//    var java.util.ArrayList<CompileResult> conseqNestedResults= new java.util.ArrayList<CompileResult>();
//    var java.util.ArrayList<CompileResult> alterNestedResults= new java.util.ArrayList<CompileResult>();
//    var java.util.ArrayList<String> namesToAdd= new java.util.ArrayList<String>();
//    
//    var CompileResult compRes
//    var altID= "alt_id"+SDMakerToCareUtils::nextID var probTabID= "alt_probs_id"+SDMakerToCareUtils::nextID
//    var int i= 0; //pour distinguer les alternants possibles
//    var java.util.ArrayList<Double> probas= new java.util.ArrayList<Double>();
//    var boolean haveSetConseqProb= false;
//    var boolean haveSetAlterProb= false;
//    var boolean goodConfigProb=
//             config.globalProbInAlt!=null&&
//             0<= config.globalProbInAlt &&
//             config.globalProbInAlt <= 1
//             
//    //CALCUL DES PROBABILITES
//    if(alt.conseq.probConseq!=null&&
//        0 < alt.conseq.probConseq &&
//        alt.conseq.probConseq <= 1){
//            
//        probas.add(alt.conseq.probConseq);
//        haveSetConseqProb= true;
//    }
//
//    if(haveSetConseqProb==false){
//        if(goodConfigProb){
//            probas.add(config.globalProbInAlt);
//        }
//    }
//    
//    for(alter : alt.alters){
//        haveSetAlterProb= false;
//        
//        if(alter.probAlter!=null&&
//            0 < alter.probAlter&&
//            alter.probAlter <=1){
//                probas.add(alter.probAlter);
//                haveSetAlterProb= true;
//        }
//        
//        if(haveSetAlterProb==false){
//            if(goodConfigProb){
//                probas.add(config.globalProbInAlt);
//            }
//        }
//    }
//    
//    //FIN CALCUL DES PROBABILITES
//	
//	
//    var CharSequence charSequenceResult=
//    '''
//«««TRAITEMENT DU CONSEQUENT»»
//    «FOR elt: alt.conseq.conseq_elts»
//«««    «IF !(elt instanceof Declaration)»
//    «SDMakerToCareUtils::toNullExp(compRes= compileEltCare(elt, context))»
//    «SDMakerToCareUtils::toNullExp(conseqNestedResults.add(compRes))»
//«««    «ENDIF»
//    «ENDFOR»
//    
//    «IF conseqNestedResults.size == 1»
//    /* CONSEQUENT: «altID» */
//    «conseqNestedResults.get(0).charSequenceResult»
//    «SDMakerToCareUtils::toNullExp(namesToAdd.add(conseqNestedResults.get(0).eltID))»
//    «ELSEIF conseqNestedResults.size > 1»
//    /* CONSEQUENT: «altID» */
//    BlockList bloc_«altID»_conseq = new BlockList();
//    
//    «FOR conseqNestedResult: conseqNestedResults»
//    «conseqNestedResult.charSequenceResult»
//    «ENDFOR»
//    
//    // adds for bloc_«altID»_conseq
//    «FOR conseqNestedResult: conseqNestedResults»
//    bloc_«altID»_conseq.add(«conseqNestedResult.eltID»);
//    «ENDFOR»
//    «SDMakerToCareUtils::toNullExp(namesToAdd.add("bloc_"+altID+"_conseq"))»
//    «ENDIF»
//
//«««TRAITEMENT DES ALTERNANTS»»
//   «SDMakerToCareUtils::toNullExp(i=0)»
//   «FOR alter: alt.alters»
//   «SDMakerToCareUtils::toNullExp(i=i+1)»
//    «alterNestedResults.clear()»
//    «FOR elt: alter.alter_elts»
//«««    «IF !(elt instanceof Declaration)»
//    «SDMakerToCareUtils::toNullExp(compRes= compileEltCare(elt, context))»
//    «SDMakerToCareUtils::toNullExp(alterNestedResults.add(compRes))»
//«««    «ENDIF»
//    «ENDFOR»
//    
//    «IF alterNestedResults.size == 1»
//    /* ALTERNATIVE «i»: «altID» */
//    «alterNestedResults.get(0).charSequenceResult»
//    «SDMakerToCareUtils::toNullExp(namesToAdd.add(alterNestedResults.get(0).eltID))»
//    //.add(«alterNestedResults.get(0).eltID»);
//    «ELSEIF alterNestedResults.size > 1»
//    /* ALTERNATIVE «i»: «altID» */
//    BlockList bloc_«altID»_alter_num_«i» = new BlockList();
//    
//    «FOR alterNestedResult: alterNestedResults»
//    «alterNestedResult.charSequenceResult»
//    «ENDFOR»
//    
//    // adds for bloc_«altID»_alter_num_«i»
//    «FOR alterNestedResult: alterNestedResults»
//    bloc_«altID»_alter_num_«i».add(«alterNestedResult.eltID»);
//    «ENDFOR»
//    «SDMakerToCareUtils::toNullExp(namesToAdd.add("bloc_"+altID+"_alter_num_"+i))»
//    «ENDIF»
//    «ENDFOR»
//
//«««FINALISATION DE L'ALTERNATIVE»»
//   // FINALIZING «altID»
//   Alt «altID»= new Alt();
//   «FOR name : namesToAdd»
//   «altID».add(«name»);
//   «ENDFOR»
//   
//   «IF (probas.size()==(1+alt.alters.size()))»
//«««   Si on a pu calculer une proba pour chaque cas
//«««   alors on peut creer un alter avec proba
//    «SDMakerToCareUtils::toNullExp(i=0)»
//   double[] «probTabID»= new double[«probas.size()»];
//   «FOR proba : probas»
//   «probTabID»[«i»]= «proba»;
//   «SDMakerToCareUtils::toNullExp(i=i+1)»
//   «ENDFOR»
//   «altID».setProbas(«probTabID»);
//   «ENDIF»
//    '''
//
//    return new CompileResult()
//                .setCharSequenceResult(charSequenceResult)
//                .setEltID(altID)
//                .setIsAddableToMainSequence(true)
//   }
//
//
//
//
//    /* *************************************
//     * Compilation des boucles *************
//     * *************************************/
//    def CompileResult compileLoopCare(Loop loop, IContext context) {
//    
//    var IConfigData config= context.getConfigData
//    var java.util.ArrayList<CompileResult> nestedResults= new java.util.ArrayList<CompileResult>();
//    var java.util.ArrayList<String> nestedEltIDs= new java.util.ArrayList<String>();
//    var CompileResult compRes
//    var loopID= "loop_id"+SDMakerToCareUtils::nextID
//    var double probContinue= -1;
//    
//  
//    if((loop.probContinue != null) &&
//       0 < loop.probContinue &&
//       loop.probContinue <= 1 ){
//        probContinue= loop.probContinue;
//    }
//    else{
//        probContinue= config.probContinueLoop;
//    }
//    
//    var CharSequence charSequenceResult=
//    '''
//
//    «FOR elt: loop.body»
//«««    «IF !(elt instanceof Declaration)»
//    «SDMakerToCareUtils::toNullExp(compRes= compileEltCare(elt, context))»
//    «SDMakerToCareUtils::toNullExp(nestedResults.add(compRes))»
//    «SDMakerToCareUtils::toNullExp(nestedEltIDs.add(compRes.eltID))»
//«««    «ENDIF»
//    «ENDFOR»
//    
//    «IF nestedEltIDs.size == 1»
//    /* LOOP: «loopID» */
//     «nestedResults.get(0).charSequenceResult»
//    «IF 0 < probContinue && probContinue <= 1 »
//    Loop «loopID» = new Loop(«nestedEltIDs.get(0)», «probContinue»);
//    «ELSE»
//    Loop «loopID» = new Loop(«nestedEltIDs.get(0)»);
//    «ENDIF»
//    «ELSEIF nestedEltIDs.size > 1»
//    /* LOOP: «loopID» */
//    BlockList bloc_«loopID» = new BlockList();
//    «FOR nestedResult: nestedResults»
//        «nestedResult.charSequenceResult»
//    «ENDFOR»
//    
//    //add(s) for «loopID»
//    «FOR eltID: nestedEltIDs»
//    bloc_«loopID».add(«eltID»);
//    «ENDFOR»
//    
//    /* FINALIZING «loopID» */
//    «IF 0 < probContinue && probContinue <= 1 »
//    Loop «loopID» = new Loop(bloc_«loopID», «probContinue»);
//    «ELSE»
//     Loop «loopID» = new Loop(bloc_«loopID»);
//    «ENDIF»
//    «ENDIF»
//    '''
//      
//    var Diagram theD= SDMakerToCareUtils::foundDiagram(loop);
//
//    return new CompileResult()
//                .setCharSequenceResult(charSequenceResult)
//                .setEltID(loopID)
//                .setIsAddableToMainSequence(true)
//    }
//
//    /* *************************************
//     * Compilation des options *************
//     * *************************************/
//     
//    def CompileResult compileOptCare(Opt opt, IContext context) {
//    
//    var IConfigData config= context.getConfigData   
//    var java.util.ArrayList<CompileResult> nestedResults= new java.util.ArrayList<CompileResult>();
//    var java.util.ArrayList<String> nestedEltIDs= new java.util.ArrayList<String>();
//    var CompileResult compRes
//    var optID= "opt_id"+SDMakerToCareUtils::nextID
//    var double probExec= -1;
//    
//    
//    if((opt.probExec != null) &&
//       0 < opt.probExec &&
//       opt.probExec <= 1 ){
//        probExec= opt.probExec;
//    }
//    else{
//        probExec= config.probExecOpt;
//    }
//
//    var CharSequence charSequenceResult=
//    '''
//    
//    «FOR elt: opt.opts»
//«««    «IF !(elt instanceof Declaration)»
//    «SDMakerToCareUtils::toNullExp(compRes= compileEltCare(elt, context))»
//    «SDMakerToCareUtils::toNullExp(nestedResults.add(compRes))»
//    «SDMakerToCareUtils::toNullExp(nestedEltIDs.add(compRes.eltID))»
//«««    «ENDIF»
//    «ENDFOR»
//    
//    «IF nestedEltIDs.size == 1»
//    /* OPT: «optID» */
//     «nestedResults.get(0).charSequenceResult»
//    «IF 0 < probExec && probExec <= 1»
//    Opt «optID» = new Opt(«nestedEltIDs.get(0)», «probExec»);
//    «ELSE»
//    Opt «optID» = new Opt(«nestedEltIDs.get(0)»);
//    «ENDIF»
//    «ELSEIF nestedEltIDs.size > 1»
//    /* OPT: «optID» */
//    BlockList bloc_«optID» = new BlockList();
//    «FOR nestedResult: nestedResults»
//    «nestedResult.charSequenceResult»
//    «ENDFOR»
//    
//    //add(s) for bloc_«optID»
//    «FOR eltID: nestedEltIDs»
//    bloc_«optID».add(«eltID»);
//    «ENDFOR»
//    
//    /* FINALIZING «optID» */
//    «IF 0 < probExec && probExec <= 1»
//    Opt «optID» = new Opt(bloc_«optID», «probExec»);
//    «ELSE»
//    Opt «optID» = new Opt(bloc_«optID»);
//    «ENDIF»
//    «ENDIF»
//    '''
//    
//    
//    return new CompileResult()
//                .setCharSequenceResult(charSequenceResult)
//                .setEltID(optID)
//                .setIsAddableToMainSequence(true)
//    }
//    
//    def CompileResult compileRefCare(DiagramRef diagramRef, IContext context){
//        var refID= "bloc_ref_id"+SDMakerToCareUtils::nextID;
//        var List<CompileResult> nestedCompileResult= new ArrayList<CompileResult>();
//        var oldRefData= context.getDiagramRefData;
//        var DiagramRefDataImpl newRefData= new DiagramRefDataImpl();
//        var IInputData oldInputData= context.getInputData();
//        var IInputData inputData= context.getInputData();
//        var Diagram d= null;
//        
//        /* On altere le contexte de generation */
//        
//        inputData= new InputDataImpl(context.getDiagramInput(diagramRef.ref));
//        context.setInput(inputData);
//        
//        d= context.findDiagram(diagramRef.ref);           
//        newRefData.init(d, diagramRef, context.getDiagramRefData, d.name);
//        context.setDiagramRefData(newRefData);
//            
//        /* On compile dans le nouveau contexte */    
//           
//        var int i= 0;
//            
//        var CharSequence charSequenceResult=
//        '''
//		//STARTING «refID»
//		
//        «FOR elt: d.diagram_elts»
//        «var CompileResult compRes = compileEltCare(elt, context)»
//        «IF compRes.isAddableToEntryPoint»
//        «SDMakerToCareUtils::toNullExp(nestedCompileResult.add(compRes))»
//        «ENDIF»
//        «compRes.charSequenceResult»
//        «ENDFOR»
//        
//        //FINALIZING «refID»
//        «IF nestedCompileResult.size > 1»
//        BlockList «refID» = new BlockList();
//        «FOR compRes: nestedCompileResult»
//        «refID».add(«compRes.eltID»);
//        «ENDFOR»
//        «ELSEIF nestedCompileResult.size == 1»
//        Block «refID»= «nestedCompileResult.get(0).eltID»;
//        «ENDIF»
//        '''
//        
//        /* On restaure le contexte */
//        
//        context.setDiagramRefData(oldRefData);
//        context.setInput(oldInputData);
//       
//        
//        return new CompileResult()
//                .setCharSequenceResult(charSequenceResult)
//                .setEltID(refID)
//                .setIsAddableToMainSequence(true);
//    }
}
